package socket

import (
	"common/comRedis"
	"common/dao/model"
	"common/response"
	"encoding/json"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"main/types"
	"time"
)

func CreateReplyMsg(content types.Response) []byte {
	msg, _ := json.Marshal(content)

	//处理逻辑

	// 群体发送到redis

	return msg
}
func setAccounts() {
	p := comRedis.RedisPrams{
		Rdb: Manager.svc.Rdb,
		Ctx: Manager.svc.Ctx,
		Key: "Accounts",
	}
	hm, err := comRedis.GetRedisString(&p)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("setAccounts", hm)
	Accounts := make(map[string][]string)
	_ = json.Unmarshal([]byte(hm), &Accounts)
	Manager.Accounts = Accounts

}

// Logic 处理消息 flag 是否发送到redis群体处理消息
func Logic(data types.RequestMessage) (*types.Response, error) {
	var (
		resp = types.Response{}
		err  error
		body response.Body
	) // 处理你的逻辑
	switch data.Type {
	case types.SendMessage:
		err := SendMessageFun(data.Data)
		if err != nil {
			return nil, err
		}
		break
	case types.AddRoom:
		d, err := addRoom(data.Data)
		if err != nil {
			return nil, err
		}
		body.Data = d
		break
	case types.LeftRoom:
		err = LeftRoom(data.Data)
		if err != nil {
			return nil, err
		}
		break
	default:
		return nil, errors.New("未匹配到消息类型")
	}
	resp.Type = types.Success
	body.Code = 1
	body.Message = "成功"
	resp.Body = body
	return &resp, nil
}

func SendMessageFun(data string) error {
	messageData, err := types.GetMessageData[model.Message](data)
	t := time.Now()
	messageData.CreateTime = &t
	if err != nil {
		return err
	}
	byString, err := types.GetStructByString(messageData)
	if err != nil {
		return err
	}
	//key := fmt.Sprintf("%s:%s", Manager.svc.Config.SubRedisKey, utils.GetUuid())
	//paras := comRedis.RedisPrams{
	//	Ctx: Manager.svc.Ctx,
	//	Rdb: Manager.svc.Rdb,
	//	Key: key,
	//}
	//err = comRedis.SetRedisString(&paras, string(byString))
	//if err != nil {
	//	return err
	//}
	Manager.svc.NC.Publish(Manager.svc.Config.SubRedisKey, byString)
	return nil
}
func LeftRoom(data string) error {
	messagesData, err := types.GetMessageData[types.LeftRoomData](data)
	if err != nil {
		return err
	}
	if messagesData.Uuid == "" {
		return errors.New("请传入 uuid")
	}
	if messagesData.GroupsId == 0 {
		return errors.New("请传入 groups_id")
	}
	if messagesData.SocketId == "" {
		return errors.New("请传入 socket_id")
	}
	var (
		d model.GroupMember
	)
	d.UserUUID = messagesData.Uuid
	d.GroupID = messagesData.GroupsId
	t := time.Now()
	d.LeftAt = &t
	db := Manager.svc.DB
	table := db.Table(model.TableNameGroupMember)
	err = table.Transaction(func(tx *gorm.DB) error {
		if err := tx.Where("group_id = ?", messagesData.GroupsId).
			Where("user_uuid = ?", messagesData.Uuid).
			Where("socket_id = ?", messagesData.SocketId).
			Select("left_at").
			Updates(&d).Error; err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return err
	}
	return nil
}
func addRoom(data string) (model.GroupMember, error) {
	var (
		d       model.GroupMember
		oldData model.GroupMember
	)
	messagesData, err := types.GetMessageData[types.AddRoomData](data)
	if err != nil {
		return d, err
	}
	if messagesData.Uuid == "" {
		return d, errors.New("请传入 uuid")
	}
	if messagesData.GroupsId == 0 {
		return d, errors.New("请传入 groups_id")
	}
	if messagesData.SocketId == "" {
		return d, errors.New("请传入 socket_id")
	}

	d.GroupID = messagesData.GroupsId
	d.UserUUID = messagesData.Uuid
	d.SocketID = messagesData.SocketId

	t := time.Now()
	d.JoinedAt = &t
	db := Manager.svc.DB
	table := db.Table(model.TableNameGroupMember)
	err = table.Transaction(func(tx *gorm.DB) error {
		if err := tx.Where("group_id = ?", messagesData.GroupsId).
			Where("user_uuid = ?", messagesData.Uuid).
			Where("socket_id = ?", messagesData.SocketId).
			Where("left_at IS NULL").First(&oldData).Error; err != nil {
			//return err
		}
		if oldData.UserUUID != "" && oldData.GroupID != 0 && oldData.SocketID != "" {
			return errors.New("你已加入过房间")
		}
		if err := tx.Create(&d).Error; err != nil {
			return err
		}
		err := NotificationMessage(d)
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return d, err
	}
	return d, nil
}
